﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ICSharpCode.SharpZipLib.Zip;
using COM.Web;
using ICSharpCode.SharpZipLib.GZip;
using WebApp.Web.Service;
using COM.Data;
using WebApp.Service;

namespace WebApp.Web.Controllers
{
    public class FileV1Controller : Controller
    {
        private IUploadFileService uploadFileService = Unity.Instance.GetService<IUploadFileService>();

        [HttpPost]
        public ActionResult Upload(string qqfilename)
        {
            try
            {
                if (Request.Files.Count != 1)
                    throw new ApplicationException("上传文件应有一个文件流.");

                HttpPostedFileBase postFile = Request.Files[0];
                if (postFile.ContentLength == 0)
                    throw new ApplicationException("空文件");

                var fileItemID = this.uploadFileService.UploadFile("TempFile", qqfilename, Request.Files[0]);
                return Json(new { success = true, fileItemID = fileItemID }, "application/json");
            }
            catch (Exception exception)
            {
                string format = "FileUploadError:{0}={1}\r\n{2}.Message:{3}\r\nStack:{4}\r\n";
                string errorInfo = string.Format(format, this.Request.HttpMethod, this.Request.Url, exception.GetType().Name, exception.Message, exception.StackTrace);
                var logErrorService = Unity.Instance.GetService<COM.Service.ILogErrorService>();
                logErrorService.LogWebAppError(errorInfo);
                return Json(new { success = false, message = "上传失败!" }, "application/json");
            }
        }

        public ActionResult Index(Guid id)
        {
            var fileInfo = this.uploadFileService.GetFileInfoByID(id);
            var fileItemService = Unity.Instance.GetService<IFileItemService>();
            var httpRequestService = Unity.Instance.GetService<IHttpRequestService>();
            var runtimeService = Unity.Instance.GetService<IRuntime>();
            var userID = runtimeService.Permission.CurrentUser.UserID;
            fileItemService.CreateFileItemDownload(fileItemID: id, ip: httpRequestService.ClientIP, beginDate: DateTime.Now, endDate: DateTime.Now, isDownloaded: true, userID:userID);
            return new DownloadResult(fileInfo.Item1, fileInfo.Item2);
        }


        public ActionResult DownloadZip()
        {
            var file = System.IO.Path.Combine(Unity.Instance.GetService<IWebAppPathService>().AppRunPath, "..", "Download", "Android", "Release", "com.winlost.androidapp-Signed.apk");
            var s = this.ZipFile(file);
            return File(s, "application/octet-stream", "AndroidApp.zip");
        }

        private byte[] ZipFile(string fileName)
        {
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            using (ZipOutputStream s = new ZipOutputStream(stream))
            {
                s.SetLevel(9); // 压缩级别 0-9
                byte[] buffer = new byte[4096]; //缓冲区大小
                ZipEntry entry = new ZipEntry(System.IO.Path.GetFileName(fileName));
                entry.DateTime = DateTime.Now;
                s.PutNextEntry(entry);
                using (var fs = System.IO.File.OpenRead(fileName))
                {
                    int sourceBytes;
                    do
                    {
                        sourceBytes = fs.Read(buffer, 0, buffer.Length);
                        s.Write(buffer, 0, sourceBytes);
                    } 
                    while (sourceBytes > 0);
                }
                s.Finish();
                var data = stream.ToArray();
                s.Close();
                return data;
            }
        }

    }


    public class DownloadResult : ActionResult
    {
        public DownloadResult()
        {
        }

        public DownloadResult(string filePath,string fileName)
        {
            this.FilePath = filePath;
            this.FileName = fileName;
        }

        public string FilePath
        {
            get;
            set;
        }

        public string FileName
        {
            get;
            set;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.AddHeader("content-type", "application/octet-stream");
            context.HttpContext.Response.AddHeader("content-disposition", "attachment; filename=" + this.FileName);
            context.HttpContext.Response.TransmitFile(this.FilePath);
        }
    }


}
